// 🔒 前端PPH计算工具 - 与后端保持一致的计算逻辑

export interface PPHCalculationInput {
  start_time: string;      // 开始时间 "HH:MM"
  end_time: string;        // 结束时间 "HH:MM"
  quantity: number;        // 完成数量
  total_people: number;    // 总人数
  working_people?: number; // 实际工作人数
  defect_quantity?: number; // 不良品数量
  rework_quantity?: number; // 返工数量
  scrap_quantity?: number;  // 报废数量
  abnormal_loss_minutes?: number;  // 异常损失时间(分钟)
  break_minutes?: number;          // 休息时间(分钟)
  changeover_minutes?: number;     // 换线时间(分钟)
  maintenance_time?: number;       // 维修时间(分钟)
}

export interface PPHCalculationResult {
  // 基础计算结果
  calculatedPPH: number;    // 计算得出的PPH
  workingMinutes: number;   // 实际工作时间(分钟)
  totalMinutes: number;     // 总时间(分钟)
  netWorkingHours: number;  // 净工作时间(小时)
  lossMinutes: number;      // 损失时间(分钟)

  // 时间利用率
  timeUtilizationRate: number; // 时间利用率(%)

  // 生产数据
  qualifiedQuantity: number;   // 合格品数量
  qualityRate: number;         // 合格率(%)
  defectRate: number;          // 不良率(%)

  // 人力分析
  totalPersonHours: number;    // 总投入人时
  effectivePersonHours: number; // 有效投入人时
  personUtilizationRate: number; // 人员利用率(%)

  // 扩展指标
  productivityIndex: number;   // 生产力指数
  personHourOutput: number;    // 人时产出
  overallEfficiency: number;   // 综合效率

  // 详细信息
  details: {
    grossMinutes: number;   // 毛时间
    netMinutes: number;     // 净时间
    lossMinutes: number;    // 损失时间
    breakdownByType: {      // 按类型分解的损失时间
      break: number;
      abnormal: number;
      changeover: number;
      maintenance: number;
    };
  };
}

export class PPHCalculationService {
  
  /**
   * 前端PPH计算 - 与后端逻辑保持一致，支持所有字段
   * PPH = 完成数量 / (净工作时间(小时) × 总人数)
   */
  calculatePPH(input: PPHCalculationInput): PPHCalculationResult {
    // 1. 计算总时间(分钟)
    const totalMinutes = this.calculateTimeDifference(input.start_time, input.end_time);

    // 2. 计算各类损失时间
    const breakMinutes = input.break_minutes || 0;
    const abnormalMinutes = input.abnormal_loss_minutes || 0;
    const changeoverMinutes = input.changeover_minutes || 0;
    const maintenanceMinutes = input.maintenance_time || 0;

    const lossMinutes = breakMinutes + abnormalMinutes + changeoverMinutes + maintenanceMinutes;

    // 3. 计算净工作时间
    const netMinutes = totalMinutes - lossMinutes;

    if (netMinutes <= 0) {
      throw new Error('净工作时间必须大于0');
    }

    // 4. 转换为小时
    const netHours = netMinutes / 60;

    // 5. 人力数据
    const totalPeople = input.total_people;
    const workingPeople = input.working_people || totalPeople;

    // 6. 生产数据
    const quantity = input.quantity;
    const defectQuantity = input.defect_quantity || 0;
    const qualifiedQuantity = quantity - defectQuantity;

    // 7. 基础PPH计算
    const calculatedPPH = quantity / (netHours * totalPeople);

    // 8. 时间利用率
    const timeUtilizationRate = (netMinutes / totalMinutes) * 100;

    // 9. 质量指标
    const qualityRate = quantity > 0 ? (qualifiedQuantity / quantity) * 100 : 0;
    const defectRate = quantity > 0 ? (defectQuantity / quantity) * 100 : 0;

    // 10. 人力指标
    const totalPersonHours = netHours * totalPeople;
    const effectivePersonHours = netHours * workingPeople;
    const personUtilizationRate = (workingPeople / totalPeople) * 100;

    // 11. 扩展指标
    const productivityIndex = quantity / netHours; // 每小时产出
    const personHourOutput = calculatedPPH; // 人时产出等于PPH
    const overallEfficiency = (timeUtilizationRate * personUtilizationRate * qualityRate) / 10000; // 综合效率

    return {
      // 基础计算结果
  calculatedPPH: Math.round(calculatedPPH * 10) / 10,
      workingMinutes: netMinutes,
      totalMinutes,
      netWorkingHours: Math.round(netHours * 100) / 100,
      lossMinutes,

      // 时间利用率
      timeUtilizationRate: Math.round(timeUtilizationRate * 100) / 100,

      // 生产数据
      qualifiedQuantity,
      qualityRate: Math.round(qualityRate * 100) / 100,
      defectRate: Math.round(defectRate * 100) / 100,

      // 人力分析
      totalPersonHours: Math.round(totalPersonHours * 100) / 100,
      effectivePersonHours: Math.round(effectivePersonHours * 100) / 100,
      personUtilizationRate: Math.round(personUtilizationRate * 100) / 100,

      // 扩展指标
      productivityIndex: Math.round(productivityIndex * 100) / 100,
      personHourOutput: Math.round(personHourOutput * 100) / 100,
      overallEfficiency: Math.round(overallEfficiency * 100) / 100,

      // 详细信息
      details: {
        grossMinutes: totalMinutes,
        netMinutes,
        lossMinutes,
        breakdownByType: {
          break: breakMinutes,
          abnormal: abnormalMinutes,
          changeover: changeoverMinutes,
          maintenance: maintenanceMinutes
        }
      }
    };
  }

  /**
   * 计算时间差(分钟)
   * 支持跨天计算
   */
  private calculateTimeDifference(startTime: string, endTime: string): number {
    const [startHour, startMinute] = startTime.split(':').map(Number);
    const [endHour, endMinute] = endTime.split(':').map(Number);
    
    const startTotalMinutes = startHour * 60 + startMinute;
    let endTotalMinutes = endHour * 60 + endMinute;
    
    // 处理跨天情况
    if (endTotalMinutes < startTotalMinutes) {
      endTotalMinutes += 24 * 60; // 加一天
    }
    
    return endTotalMinutes - startTotalMinutes;
  }

  /**
   * 计算效率达成率
   */
  calculateEfficiencyRate(actualPPH: number, targetPPH: number): number {
    if (targetPPH <= 0) return 0;
    const rate = (actualPPH / targetPPH) * 100;
    return Math.round(rate * 100) / 100; // 保留2位小数
  }

  /**
   * 验证时间格式
   */
  isValidTimeFormat(time: string): boolean {
    const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
    return timeRegex.test(time);
  }

  /**
   * 格式化时间显示
   */
  formatMinutes(minutes: number): string {
    const hours = Math.floor(minutes / 60);
    const mins = Math.round(minutes % 60);
    
    if (hours > 0) {
      return `${hours}小时${mins}分钟`;
    } else {
      return `${mins}分钟`;
    }
  }

  /**
   * 获取时间段描述
   */
  getTimeRangeDescription(startTime: string, endTime: string): string {
    const totalMinutes = this.calculateTimeDifference(startTime, endTime);
    const hours = Math.floor(totalMinutes / 60);
    const minutes = totalMinutes % 60;
    
    return `${startTime} - ${endTime} (${hours}小时${minutes}分钟)`;
  }
}
